#include <ObjectInspectorWindow.h>
#include <QToolBar>
#include <iostream>
#include <ModeControlDialog.h>
#include <EDesignerCore.h>
#include <CommandManager.h>
#include <Commands.h>
ObjectInspectorWindow::ObjectInspectorWindow( QWidget *parent /*= 0*/ ) : WindowBase(parent)
{
    m_objectInspector = new ObjectInspector(this);
    setCentralWidget(m_objectInspector->getTreeView());

    m_objectInspector->getTreeView()->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
    QObject::connect(m_objectInspector->getTreeView(), SIGNAL(customContextMenuRequested(const QPoint & )), this, SLOT(onTreeViewContextMenuRequested(const QPoint & )));

	setWindowTitle("Object Inspector");

    //初始化按钮
    //QAction* action_add_up = new QAction(QIcon("resource/action_add_up.png"), QString("Add up"),0);
    QAction* action_add_down = new QAction(QIcon("resource/action_add_down.png"), QString("Add down"),0);
    QAction* action_delete_node = new QAction(QIcon("resource/action_delete_node.png"), QString("Delete Node"),0);
    QAction* action_change_node_parent = new QAction(QIcon("resource/action_change_node_parent.png"), QString("Change Node Parent"),0);
    QAction* action_copy_node =new QAction(QIcon("resource/action_copy_node.png"), QString("Copy Node"),0);
    QAction* action_expansion_node =new QAction(QIcon("resource/action_expansion_treeItem.png"), QString("Expand Node"),0);
    QAction* action_contract_node =new QAction(QIcon("resource/action_contract_treeItem.png"), QString("Contract Node"),0);
    QAction* action_refresh_node =new QAction(QIcon("resource/action_refresh.png"), QString("Refresh"),0);

    //m_actionList.push_back(action_add_up);
    m_actionList.push_back(action_add_down);
    m_actionList.push_back(action_delete_node);
    m_actionList.push_back(action_change_node_parent);
    m_actionList.push_back(action_copy_node);
    m_actionList.push_back(action_expansion_node);
    m_actionList.push_back(action_contract_node);
    m_actionList.push_back(action_refresh_node);
    //QObject::connect(action_add_up, SIGNAL(triggered()), this, SLOT(actionAddUpTriggered()));
    QObject::connect(action_add_down, SIGNAL(triggered()), this, SLOT(actionAddDownTriggered()));
    QObject::connect(action_delete_node, SIGNAL(triggered()), this, SLOT(actionDeleteNodeTriggered()));
    QObject::connect(action_change_node_parent, SIGNAL(triggered()), this, SLOT(actionChangeNodeParentTriggered()));
    QObject::connect(action_copy_node, SIGNAL(triggered()), this, SLOT(actionCopyNodeTriggered()));
    QObject::connect(action_expansion_node, SIGNAL(triggered()), this, SLOT(actionExpansionNodeTriggered()));
    QObject::connect(action_contract_node, SIGNAL(triggered()), this, SLOT(actionContractNodeTriggered()));
    QObject::connect(action_refresh_node, SIGNAL(triggered()), this, SLOT(actionRefreshTriggered()));

    QToolBar* tool_bar = new QToolBar();
    tool_bar->addActions(m_actionList);
    this->addToolBar(tool_bar);

    //填充菜单
    m_menu = new QMenu(QString("Object Inspector"));
    m_menu->addActions(m_actionList);

    m_menuPop = new QMenu(QString("Object Inspector POp"));
    m_menuPop->addActions(m_actionList);

    getWindowShowHideAction()->setText("Object Inspector");
    getWindowShowHideAction()->setChecked(true);

    getDockWidget()->setWindowTitle("Object Inspector");

}

ObjectInspectorWindow::~ObjectInspectorWindow()
{

}

Qt::DockWidgetArea ObjectInspectorWindow::dockWidgetArea()
{
	return Qt::DockWidgetArea::RightDockWidgetArea;
}

void ObjectInspectorWindow::replaceObjectInspectorModel( ObjectInspectorModel* model )
{
    m_objectInspector->replaceModel(model);
}

void ObjectInspectorWindow::addDirector(QSharedPointer<ObjectInspectorDirector> director)
{
    m_objectInspector->addDirector(director);
    m_menuPop->addActions(director->getActionList());
}

void ObjectInspectorWindow::rebuild()
{
    m_objectInspector->rebuild();
}

void ObjectInspectorWindow::refresh()
{
    m_objectInspector->refresh();
}

void ObjectInspectorWindow::clear()
{
    m_objectInspector->clear();
}

QList<QAction *> ObjectInspectorWindow::getActionList()
{
    return m_actionList;
}

QMenu *ObjectInspectorWindow::getWindowBaseMenu()
{
    return m_menu;
}

QStandardItem *ObjectInspectorWindow::getCurrentItemPrt()
{
    QStandardItem * item_ptr= NULL;
    QModelIndex current_index = m_objectInspector->getTreeView()->currentIndex();
    if(current_index.isValid() == true)
    {
        item_ptr = m_objectInspector->getObjectInspectorModel()->itemFromIndex(current_index);
    }

    return item_ptr;
}

QStandardItem *ObjectInspectorWindow::getRootItemPtr()
{
    QStandardItem * item_ptr= NULL;
    item_ptr = m_objectInspector->getObjectInspectorModel()->invisibleRootItem();

    return item_ptr;
}

ObjectInspectorItem *ObjectInspectorWindow::addDown(QStandardItem *parentStandardItem, const QString &typeName)
{
    ObjectInspectorItem* parentItem = dynamic_cast<ObjectInspectorItem*>(parentStandardItem);
    if(parentItem == NULL)
    {
        EObject* newObj = EDesignerCore::instance()->creatObject(typeName);
        if(newObj == NULL) return NULL;
        parentStandardItem->appendRow(newObj->getObjItem());
        return newObj->getObjItem();
    }

    EObject* parentObj = parentItem->getObjectPtr().data();
    if(parentObj == NULL) return NULL;
    EObject* newObj = EDesignerCore::instance()->creatObject(typeName);
    if(newObj == NULL) return NULL;
    /**/
    QList<QSharedPointer<ObjectInspectorDirector>> director_list = m_objectInspector->getObjectInspectorModel()->getDirectorList();
    for(int i = 0; i < director_list.size(); i++)
    {
        if(director_list.at(i)->addItemDown(parentObj,newObj))
        {
            parentObj->getObjItem()->appendRow(newObj->getObjItem());
            return newObj->getObjItem();

        }
    }
    delete newObj->getObjItem();
    return NULL;
}

void ObjectInspectorWindow::hideMenuObjectInspector()
{
    m_menu->menuAction()->setVisible(false);
}

void ObjectInspectorWindow::actionAddUpTriggered()
{
    QString class_type = EDesignerCore::instance()->modeControlDialog()->enterSelectClassTypeMode();

    CommandAddObject* command_add_object = new CommandAddObject;
    EDesignerCore::instance()->commandManager()->pushCommand(command_add_object);
    //std::cout<<"slot add up"<<std::endl;
}

void ObjectInspectorWindow::actionAddDownTriggered()
{

    //判断当前选择的item
    QModelIndex current_index = m_objectInspector->getTreeView()->currentIndex();
    QStandardItem* item_ptr;
    if(current_index.isValid() == false)
    {
        item_ptr = m_objectInspector->getObjectInspectorModel()->invisibleRootItem();
    }
    else
    {
        item_ptr = m_objectInspector->getObjectInspectorModel()->itemFromIndex(current_index);
    }

    ObjectInspectorItem* object_item_ptr = dynamic_cast<ObjectInspectorItem*>(item_ptr);
    if(object_item_ptr == NULL)
    {
        return;
    }
    QString class_type = EDesignerCore::instance()->modeControlDialog()->enterSelectClassTypeMode();
    if(class_type == "-1")
    {
        return;
    }

    EObject* newObj = EDesignerCore::instance()->creatObject(class_type);
    if(newObj == NULL) return;
    EObject* parentObj = object_item_ptr->getObjectPtr().data();
    if(parentObj == NULL) return;
    /**/
    QList<QSharedPointer<ObjectInspectorDirector>> director_list = m_objectInspector->getObjectInspectorModel()->getDirectorList();
    for(int i = 0; i < director_list.size(); i++)
    {
        if(director_list.at(i)->addItemDown(parentObj,newObj))
        {
            newObj->refreshItemTest();
            parentObj->getObjItem()->appendRow(newObj->getObjItem());
            selectObjItem(newObj->getObjItem());

            break;
        }
    }

    //this->refresh();


    CommandAddObject* command_add_object = new CommandAddObject;//使用commond类可以在日后实现redo，undo命令，
    EDesignerCore::instance()->commandManager()->pushCommand(command_add_object);

    //std::cout<<"slot add down"<<std::endl;
}

void ObjectInspectorWindow::actionDeleteNodeTriggered()
{
    //判断当前选择的item

    QList<QSharedPointer<ObjectInspectorDirector>> director_list = m_objectInspector->getObjectInspectorModel()->getDirectorList();
    QList<QModelIndex> selected_indexes = m_objectInspector->getTreeView()->selectionModel()->selectedIndexes();
    QList<ObjectInspectorItem*> item_list;
    for(int i = 0; i<selected_indexes.size(); i++)
    {
        QStandardItem* item_ptr = m_objectInspector->getObjectInspectorModel()->itemFromIndex(selected_indexes.at(i));
        //std::cout<<item_ptr->text().toStdString()<<std::endl;
        ObjectInspectorItem* object_item_ptr = dynamic_cast<ObjectInspectorItem*>(item_ptr);
        if(object_item_ptr != NULL)
        {
            item_list.push_back(object_item_ptr);


        }
    }
    for(int j = 0 ; j < item_list.size(); j++)
    {
        ObjectInspectorItem* object_item_ptr = dynamic_cast<ObjectInspectorItem*>(item_list.at(j));
        if(object_item_ptr == NULL)return;
        EObject* objPtr = object_item_ptr->getObjectPtr().data();
        for(int i = 0; i < director_list.size(); i++)
        {
            if(director_list.at(i)->deleteItem(objPtr))
            {
                //object_item_ptr->removeFromParent();
                object_item_ptr->takeFromParent();
                delete object_item_ptr;
               // EDesignerCore::instance()->getRootItemPtr()->appendRow(objPtr->getObjItem());

                break;
            }
        }
     }

}

void ObjectInspectorWindow::actionChangeNodeParentTriggered()
{
//    std::cout<<"change parent"<<std::endl;


    QList<QSharedPointer<ObjectInspectorDirector>> director_list = m_objectInspector->getObjectInspectorModel()->getDirectorList();
    QList<QModelIndex> selected_indexes = m_objectInspector->getTreeView()->selectionModel()->selectedIndexes();
    QList<ObjectInspectorItem*> item_list;
    if(selected_indexes.size() <= 1 ) return;
    for(int i = 0; i<selected_indexes.size(); i++)
    {
        QStandardItem* item_ptr = m_objectInspector->getObjectInspectorModel()->itemFromIndex(selected_indexes.at(i));
        //std::cout<<item_ptr->text().toStdString()<<std::endl;
        ObjectInspectorItem* object_item_ptr = dynamic_cast<ObjectInspectorItem*>(item_ptr);
        if(object_item_ptr != NULL)
        {
            item_list.push_back(object_item_ptr);
            //object_item_ptr->takeFromParent();

        }
    }
    for(int j = 0 ; j < item_list.size()-1; j++)
    {
        ObjectInspectorItem* object_item_ptr = dynamic_cast<ObjectInspectorItem*>(item_list.at(j));
        if(object_item_ptr == NULL)return;
        EObject* childObj = object_item_ptr->getObjectPtr().data();
        EObject* parentObj = item_list.at( item_list.size() -1 )->getObjectPtr().data();
        for(int i = 0; i < director_list.size(); i++)
        {
            if(director_list.at(i)->changeItemParent(parentObj, childObj) )
            {
                //object_item_ptr->removeFromParent();
                //delete object_item_ptr;
                object_item_ptr->changeParent(item_list.at( item_list.size() -1 ));
                break;
            }
        }
     }

}

void ObjectInspectorWindow::actionCopyNodeTriggered()
{
    //std::cout<<"actionCopyNodeTriggered"<<std::endl;
    /*
    QList<QModelIndex> selected_indexes = m_objectInspector->getTreeView()->selectionModel()->selectedIndexes();
    QList<ObjectInspectorItem*> item_list;
    for(int i = 0; i<selected_indexes.size(); i++)
    {
        QStandardItem* item_ptr = m_objectInspector->getObjectInspectorModel()->itemFromIndex(selected_indexes.at(i));
        //std::cout<<item_ptr->text().toStdString()<<std::endl;
        ObjectInspectorItem* object_item_ptr = dynamic_cast<ObjectInspectorItem*>(item_ptr);
        if(object_item_ptr != NULL)
        {
            item_list.push_back(object_item_ptr);
        }
    }
    //
    QList<QSharedPointer<ObjectInspectorDirector>> director_list = m_objectInspector->getObjectInspectorModel()->getDirectorList();
    for(int i = 0; i < director_list.size(); i++)
    {
        director_list.at(i)->copyItem(item_list);
    }
*/
    QList<QSharedPointer<ObjectInspectorDirector>> director_list = m_objectInspector->getObjectInspectorModel()->getDirectorList();
    QList<QModelIndex> selected_indexes = m_objectInspector->getTreeView()->selectionModel()->selectedIndexes();
    QList<ObjectInspectorItem*> item_list;
    //if(selected_indexes.size() <= 1 ) return;
    for(int i = 0; i<selected_indexes.size(); i++)
    {
        QStandardItem* item_ptr = m_objectInspector->getObjectInspectorModel()->itemFromIndex(selected_indexes.at(i));
        //std::cout<<item_ptr->text().toStdString()<<std::endl;
        ObjectInspectorItem* object_item_ptr = dynamic_cast<ObjectInspectorItem*>(item_ptr);
        if(object_item_ptr != NULL)
        {
            item_list.push_back(object_item_ptr);
            //object_item_ptr->takeFromParent();

        }
    }
    for(int j = 0 ; j < item_list.size(); j++)
    {
        ObjectInspectorItem* object_item_ptr = dynamic_cast<ObjectInspectorItem*>(item_list.at(j));
        if(object_item_ptr == NULL)return;
        EObject* objPtr = object_item_ptr->getObjectPtr().data();

        for(int i = 0; i < director_list.size(); i++)
        {
            if(director_list.at(i)->copyItem(objPtr) )
            {
                //object_item_ptr->removeFromParent();
                //delete object_item_ptr;
                //object_item_ptr->changeParent(item_list.at( item_list.size() -1 ));
                EObject* newObj = objPtr->clone();
                //director_list.at(i)->addItemDown(newObj)
                object_item_ptr->parent()->appendRow(newObj->getObjItem());

                break;
            }
        }
     }

}

void ObjectInspectorWindow::actionExpansionNodeTriggered()
{
    QModelIndex current_index = m_objectInspector->getTreeView()->currentIndex();
    QStandardItem* item_ptr;
    if(current_index.isValid() == false)
    {
        item_ptr = m_objectInspector->getObjectInspectorModel()->invisibleRootItem();
    }
    else
    {
        item_ptr = m_objectInspector->getObjectInspectorModel()->itemFromIndex(current_index);
    }

    ObjectInspectorItem* object_item_ptr = dynamic_cast<ObjectInspectorItem*>(item_ptr);
    if(object_item_ptr == NULL)return;
    m_objectInspector->getTreeView()->setExpanded(current_index, true);
}

void ObjectInspectorWindow::actionContractNodeTriggered()
{

    QModelIndex current_index = m_objectInspector->getTreeView()->currentIndex();
    QStandardItem* item_ptr;
    if(current_index.isValid() == false)
    {
        item_ptr = m_objectInspector->getObjectInspectorModel()->invisibleRootItem();
    }
    else
    {
        item_ptr = m_objectInspector->getObjectInspectorModel()->itemFromIndex(current_index);
    }

    ObjectInspectorItem* object_item_ptr = dynamic_cast<ObjectInspectorItem*>(item_ptr);
    if(object_item_ptr == NULL)return;
    m_objectInspector->getTreeView()->setExpanded(current_index, false);

}

void ObjectInspectorWindow::actionRefreshTriggered()
{
    QList<QSharedPointer<ObjectInspectorDirector>> director_list = m_objectInspector->getObjectInspectorModel()->getDirectorList();
    for(int i = 0; i < director_list.size(); i++)
    {
        director_list.at(i)->refresh();

    }
}

void ObjectInspectorWindow::onTreeViewContextMenuRequested(const QPoint &pos)
{
    std::cout<<"ObjectInspectorWindow::onTreeViewContextMenuRequested"<<std::endl;
    m_menuPop->exec(QCursor::pos());
}

void ObjectInspectorWindow::selectObjItem(QStandardItem *itemPtr)
{
    QModelIndex itemIndex = m_objectInspector->getObjectInspectorModel()->indexFromItem(itemPtr);
    if(itemIndex.isValid() == false)return;
    m_objectInspector->getTreeView()->selectionModel()->select(itemIndex, QItemSelectionModel::SelectionFlag::Select);
}
